package clock.socoolby.com.clock.widget.animatorview.animator;


//引用自:https://github.com/YuToo/FluorescenceView/

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RadialGradient;
import android.graphics.Shader;

import java.util.LinkedList;
import java.util.List;

import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;

public class FluorescenceAnimator extends AbstractAnimator<FluorescenceAnimator.Particle> {

    private int     mParticleRadius = 15;          // 粒子大小基数
    private int     mParticleRandomRadius = 50;    // 随机范围(基数上范围)
    private int     mParticleLife = 3000;          //生命基数（毫秒）
    private int     mParticleRandomLife = 8000;        //随机范围（基数上范围）
    private int     mParticleNum = 20;           //粒子数量
    private int[]   mParticleColors = {0xFF0d4289, 0xff034aa1,0x887b0808, 0xff176bd1, 0xff1f39ff,0x33d4ed00, 0x66ffffff, 0xff777800, 0xff0e2569};//粒子颜色集合
    private Paint mPaint;

    List<Particle> cache = new LinkedList<>();

    public FluorescenceAnimator() {
        super(DYNAMIC_QUANTITY);
    }

    @Override
    public boolean run() {
        for(Particle particle : list){
            if(particle.getLife() <= 0){
                cache.add(particle);
            }
        }
        list.removeAll(cache);
        for(int i = 0 ; i < mParticleNum - list.size() ; i ++){
            list.add(randomParticle());
        }
        cache.clear();
        return true;
    }


    @Override
    public Particle createNewEntry() {
        return randomParticle();
    }

    @Override
    protected void initPaint(Paint mPaint) {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
    }

    private Particle randomParticle(){
        Particle particle = new Particle();
        // 随机起始位置
        PointF startP = new PointF(rand.nextInt(width), rand.nextInt(height));
        //随机结束位置
        PointF endP = new PointF(rand.nextInt(width), rand.nextInt(height));
        particle.setStartPointF(startP);
        particle.setEndPointF(endP);
        // 随机生命
        particle.setLife(mParticleLife + rand.nextInt(mParticleRandomLife));
        // 随机大小
        particle.setRadius(mParticleRadius + rand.nextInt(mParticleRandomRadius));
        // 随机颜色
        particle.setColor(mParticleColors[rand.nextInt(mParticleColors.length)]);
        return particle;
    }

    /**
     * Created by YuToo on 2017/2/28.
     * 荧光对象
     */
    public static class Particle implements I_AnimatorEntry {

        private PointF startPointF;//荧光开始坐标
        private PointF endPointF;//荧光结束点坐标
        private float radius;// 荧光半径
        private long startTime;//开始时间
        private int life;   //生命
        private int color;//颜色

        public Particle(){
            startTime = System.currentTimeMillis();
        }

        public PointF getStartPointF() {
            return startPointF;
        }

        public void setStartPointF(PointF startPointF) {
            this.startPointF = startPointF;
        }

        public PointF getEndPointF() {
            return endPointF;
        }

        public void setEndPointF(PointF endPointF) {
            this.endPointF = endPointF;
        }

        public float getRadius() {
            return radius;
        }

        public void setRadius(float radius) {
            this.radius = radius;
        }

        public long getStartTime() {
            return startTime;
        }

        public void setLife(int life) {
            this.life = life;
        }

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
        }

        //获取粒子透明度:先透明再实体再透明（二次函数）
        public float getTranslate(){
            // 根据生命计算透明度
            int life = getLife();
            if(life <= 0){
                return 0;
            }else{
                // y = 4x - 4x的平方
                float x = (life * 1.0f / this.life);
                return 4 * x *(1 - x);
            }
        }

        // 获取当前位置
        public PointF getPoint(){
            int life = getLife();
            if(life <= 0){
                return null;
            }else{
                PointF pointF = new PointF();
                pointF.x = endPointF.x + (endPointF.x - startPointF.x) * (life * 1.0f / this.life);
                pointF.y = endPointF.y + (endPointF.y - startPointF.y) * (life * 1.0f / this.life);
                return pointF;
            }
        }

        //获取剩余生命
        public int getLife(){
            return (int)(startTime + life - System.currentTimeMillis());
        }

        @Override
        public void move(int maxWidth, int maxHight) {

        }

        @Override
        public void onDraw(Canvas canvas,Paint mPaint) {
            PointF point = this.getPoint();
            if(point == null){
                return;
            }
            Shader shader =  new RadialGradient(point.x, point.y, radius, color, 0x00000000, Shader.TileMode.CLAMP);
            mPaint.setShader(shader);
            mPaint.setAlpha((int)(getTranslate() * 255));
            canvas.drawCircle(point.x, point.y, getRadius(), mPaint);
        }
    }
}
